﻿using System;
using System.Runtime.InteropServices;

namespace InterfaceApp
{
    class Progarm
    {
        static void Main(string[] args)
        {
            // C#中COM接口是可以实例化，但其实这种写法是使接口“映射”到某一个类上，实际上创建是这个类的实例。
            IWorker worker = new IWorker();
            // 利用 .NET Reflector 查看时可以很明显的看到 Main 方法里面的代码是：
            // IWorker worker = new James1();
            Console.ReadKey();
        }
    }

    class James1 : IWorker
    {
        public void Work(string s)
        {
            Console.WriteLine("我的名字是James1，我的工作是" + s);
        }
    }

    [ComImport, CoClass(typeof(James1))]
    [Guid("d60908eb-fd5a-4d3c-9392-8646fcd1edce")]
    public interface IWorker { void Work(string s); }
    // ComImport特性发生在tlbimp.exe导入COM类型类库的时候，生成的托管类型标记有ComImport特性
    // Guid特性是一个GUID标识，COM类型是用GUID来标识的。
}

/*
 
4.接口和抽象类的区别

接口用于规范，抽象类用于共性。抽象类是类，所以只能被单继承，但是接口却可以一次实现多个。

接口中只能声明方法，属性，事件，索引器。而抽象类中可以有方法的实现，也可以定义非静态的类变量。

抽象类可以提供某些方法的部分实现，接口不可以。抽象类的实例是它的子类给出的。接口的实例是实现接口的类给出的。

在抽象类中加入一个方法，那么它的子类就同时有了这个方法。而在接口中加入新的方法，那么实现它的类就要重新编写（这就是为什么说接口是一个类的规范了）。

接口成员被定义为公共的，但抽象类的成员也可以是私有的、受保护的、内部的或受保护的内部成员（其中受保护的内部成员只能在应用程序的代码或派生类中访问）。

此外接口不能包含字段、构造函数、析构函数、静态成员或常量。

还有一点，我们在VS中实现接口时会发现有2个选项，一个是实现接口，一个是显示实现接口。实现接口就是我们平常理解的实现接口，而显示实现接口的话，实现的方法是属于接口的，而不是属于实现类的。

 */